# -* - coding: UTF-8 -* -
import logging,time
#reload(sys)
#sys.setdefaultencoding('utf8')
from driver import QueueDriver
import redis
#队列驱动抽像类
class RedisQueue(QueueDriver):  
	def create(self):  
		self.queue_host = self.config.get('queue_server','host','localhost')
		self.queue_port = self.config.get_int('queue_server','port',6379)
		self.queue_user = self.config.get('queue_server','user','guest')
		self.queue_pass = self.config.get('queue_server','pass','')
		self.namespace = self.config.get('queue_server','queue_name','default')
		#self.queue_name = self.config.get('queue_server','queue_name','default')
		self.prefetch_count = self.config.get_int('queue_server','prefetch_count',0)
		self.queue_capacity = self.config.get_int('queue_server','capacity',0)
		self.key = 'queue:'+self.queue_name
		self.key_time = 'queue:'+self.queue_name+':at'
		self.started=True
		host_list = self.queue_host.split(',')   #HA中有多个rabbit主机
		for host in host_list: #依次链接rabbit，知道链接成功
			try:
				self.channel= redis.Redis(host=host,port=self.queue_port,password=self.queue_pass)
				break
			except Exception as e:
				#logger.error("connect rabbitmq failed: %s" % e)
				 pass


	def get(self, block=True, timeout=None):
		if block:
			item = self.channel.blpop(self.key, timeout=timeout)
		else:
			item = self.channel.lpop(self.key)

		if not item:
			item = self.channel.zrangebyscore(self.key_time, 0,time.time(),0,1)
			if item:
				item=item[0]
				self.channel.zrem(self.key_time,item)
			
		return item

	def qsize(self):
		"""Return the approximate size of the queue."""
		return self.channel.llen(self.queue_name)

	def empty(self):
		"""Return True if the queue is empty, False otherwise."""
		return self.qsize() == 0

	def put(self, item):
		"""Put item into the queue."""
		self.channel.rpush(self.queue_name, item)

	def listen(self,on_request):
		try:
			self.create()
			
			if self.channel:
				#request(self, ch, method, props, body)
				while(self.started):
					result=self.get(False)
					if result:
						try:
							on_request('','','',result)
						except Exception as e:
							
							logging.exception(e)
					time.sleep(1)
				return True
			else:
				return False
		except Exception as e:
			logging.exception(e)

	def send(self,body,args={}):
		if self.channel:
			self.put(body)
			return True
		else:
			return False			
	def stop(self):
		if self.channel:
			self.started=False
			return True
		else:
			return False
 